/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package formula.one.urjc.carrera;

import com.sun.java_cup.internal.runtime.Symbol;
import formula.one.urjc.piloto.Piloto;
import formula.one.urjc.escuderia.Coche;
import formula.one.urjc.circuito.Circuito;
import formula.one.urjc.escuderia.Escuderia;
import java.util.ArrayList;
import formula.one.urjc.rank.Rank;
import java.io.Serializable;
import java.util.Collections;
import java.util.Comparator;

/**
 *
 * @author valvarez
 */

//INCOMPLETO FALTA POR DESARROLLAR

public class Carrera implements Serializable {
    
    //necesita un circuito donde desarrollar la carrera
    private Circuito circuito;
    private final static int[] PUNTOS={25,18,15,12,10,8,6,4,2,1};
    private final static int[] SPONSOR={100000,75000,50000,25000,15000,1000};
    /*ARRAYLIST CON LOS PUNTOS PARA CADA PILOTO*/
   
    //private ArrayList<Integer> puntos ;
    
    /*SE ALMACENAN NOMBRES Y PUNTOS*/
    
    private ArrayList<Rank> clasificacion ; 
    
    private ArrayList<Escuderia> escuderias;
    
    
    //se crea el objeto carrera
    public Carrera(Circuito circuito, ArrayList<Escuderia> escuderias) {
        this.circuito = circuito;
        this.escuderias = escuderias;
        clasificacion=new ArrayList<Rank>();
        //setPuntos() ;
    }
    
    /*este método simulará una carrera
     * para ello recorrerá el listado de competidores de cada escudería para 
     * ir asignado uno a uno el tiempo. Para que un piloto Coche de la lista 
     * de competidores pueda competir
     * primero se hará el pago del canon del circuito (un pago por coche de escudería),
     * y el pago del sueldo del piloto. De no tener presupuesto suficiente, 
     * el piloto no puede competir, y se almacenará
     * con un tiempo de 0. (esto hay que tenerlo en cuenta a la hora de asignar premios.
     * Con el piloto y el tiempo se creará un objeto rank que se almacenará
     * en el listado clasificación
     * una vez finalizada la carrera se ordenará el array clasificación por tiempo, 
     * (de menor a mayor), y después, teniendo en cuenta esta clasificación, 
     * se asignan los puntos a la escudería
     * y al piloto
     */
    
    public void doCarrera(){
        
        Piloto p=null;
        int index=0;
        Coche c;
        double pago;
        boolean comp;
        comp=false;
        double time;     
        int contCompetidores = 0 ;
        
        System.out.println("Tamaño escuderias: " + escuderias.size()) ;
        for (int i=0;i < escuderias.size();i++){
            System.out.println("Entramos 1") ;
            //compruebo si existe listado de competidores, si no habrá que crear uno automático
            if(escuderias.get(i).getListaCompetidores().isEmpty()){
                escuderias.get(i).crearListaAutomCompetidores();
            }
            for (int j=0; j<escuderias.get(i).getListaCompetidores().size();j++){
                System.out.println("Entramos 2") ;
                       p =escuderias.get(i).getListaCompetidores().get(j).getPiloto();
                       System.out.println("p: " + p) ;
                       c =escuderias.get(i).getListaCompetidores().get(j).getCoche();
                                  
                       
                       pago = p.getSueldo() + circuito.getCanon();
                       
                       //comp = escuderias.get(i).comprobarPresupuesto(pago);
                       if (escuderias.get(i).hacerPago(pago)) {                           
                          time = tiempo(p, c, circuito);
                          
                       }
                       else
                           {
                                time = 0;
                               
                           }
                        rellenarClasificacion(p, time);
            contCompetidores++ ;
            }
                                                      
		}
        //ordeno el array de clasificación por tiempo de mayor a menor
        Collections.sort(clasificacion, new Comparator() {
        @Override
        public int compare(Object o1, Object o2) {
				return new Double(((Rank)o2).getTiempo()).compareTo(new Double(((Rank)o1).getTiempo()));
			}
			
		});
        
        int puntos;
        puntos=0;
        System.out.println("Número de competidores: " + contCompetidores) ;
        for (int i=0 ; i<clasificacion.size();i++){
            //si ha corrido la carrera
            if(clasificacion.get(i).getTiempo()>0){
                index=i;
                //System.out.println("Entramos a los puntos " + i) ;
                p=clasificacion.get(i).getPiloto();
                //System.out.println("Piloto p: " + p.toString()) ;
                //System.out.println("Puntos objeto: " + p.getPuntos()) ;
                //System.out.println("Tiempo Objeto: " + clasificacion.get(i).getTiempo());
                //System.out.println("Puntos Nuevos: " + this.puntos.get(i)) ;
                //System.out.println("Puntos nuevos: " + this.getPuntos().get(i)) ;
            
                puntos = p.getPuntos() + PUNTOS[i];
                p.setPuntos(puntos);
                //System.out.println("Piloto p: " + p.toString()) ;
            }
            
        }
        
        //sumar puntos y sponsor a escuderia
        incrementarEscuderias(p,index);
    }

    /*
     * Método que se encargará una vez hecha la clasificaión de sumar los puntos y el pago correspondiente del sponsor
     */
    private void incrementarEscuderias(Piloto p, int index){
        //recorro las esciderias
        for(int i=0; i<escuderias.size();i++){
            //recorro los competidores
            for (int a=0;a<escuderias.get(i).getListaCompetidores().size();a++){
                //recorro la clasificación
                for(int j=0;j<clasificacion.size();j++){
                    System.out.println(i+"_"+a+"-"+j);
                    //si el piloto ha corrido la carrera
                   if(clasificacion.get(j).getTiempo()>0){
                       
                        if(escuderias.get(i).getListaCompetidores().get(a).getPiloto().getApellidos().equals(clasificacion.get(j).getPiloto().getApellidos()) &&
                           escuderias.get(i).getListaCompetidores().get(a).getPiloto().getNombre().equals(clasificacion.get(j).getPiloto().getNombre())){
                            //Sumo los puntos correspondientes a escuderia
                            if (j<10){
                                 escuderias.get(i).setPuntos(escuderias.get(i).getPuntos()+PUNTOS[j]);
                            }
                           if (j<6){
                               //sumo al presupuesto el pago del sponsor
                            escuderias.get(i).setPresupuesto(escuderias.get(i).getPresupuesto()+SPONSOR[j]);
                           }
                            
                            break;
                        }
                   }
                    
                }
                
            }
        }
        
    }
    
    public ArrayList<Rank> getClasificacion() {
        return clasificacion;
    }

    public void setClasificacion(ArrayList<Rank> clasificacion) {
        this.clasificacion = clasificacion;
    }
   
    /*public ArrayList<Integer> getPuntos() {
        return puntos;
    }*/
    
    
    /*public void setPuntos(){
        
        ArrayList<Integer> puntos_circuito = new ArrayList<Integer>() ;
        puntos_circuito.add(25) ;
        puntos_circuito.add(18) ;
        puntos_circuito.add(15) ;
        puntos_circuito.add(12) ;
        puntos_circuito.add(10) ;
        puntos_circuito.add(8) ;
        puntos_circuito.add(6) ;
        puntos_circuito.add(4) ;
        puntos_circuito.add(1) ;
        puntos_circuito.add(0) ;
        this.puntos = puntos_circuito;
        
    }*/
    
    public double tiempo( Piloto pil , Coche coch, Circuito circ ){
        
        //v = e/t <-> t=v/e
        
        double tiempo=0;
        
        ArrayList<Double> listacurvas = circ.getCurvas();
        
        //TIEMPO EN CURVAS
        
        for(int i=0 ; i < listacurvas.size() ; i++){
            
            tiempo += coch.getCualidades().maxVelCurva()/listacurvas.get(i);
            
        }
        
        //TIEMPO EN RECTAS
        
        ArrayList<Double> listarectas = circ.getRectas();
        
        for(int i=0 ; i < listarectas.size() ; i++){
            
            tiempo += coch.getCualidades().maxVelRecta()/listarectas.get(i);
            
        }
        //se le resta 0.1 segundos en relación a la valoración del piloto
        tiempo -= (pil.getValoracion())*0.1;
                
        return tiempo ;
    }
    
    public void rellenarClasificacion(Piloto p , double tiempo){
        
        Rank r = new Rank(tiempo,p);
        
        clasificacion.add(r);     
              
    }
    
    public Circuito getCircuito(){
        return this.circuito;
    }
    
    
    @Override
    
    public String toString() {
        return "Carrera: { + Circuito = " + circuito + "\n" +
                            //"Puntos = " + puntos.size() + "\n" +
                            "Clasificación = " + clasificacion.size() + "\n" +
                            "Escuderias = " + escuderias.size() +
               "}" ;
    }
    
    public String getInfoCarrera(){
        String info="Carrera "+getCircuito().getNombre()+"\n";
        for(int i=0;i<escuderias.size();i++){
            info+=escuderias.get(i).getNombre()+"-> presupuesto:"+escuderias.get(i).getPresupuesto()+" puntos:"+escuderias.get(i).getPuntos()+"\n";
            for(int a=0;a<escuderias.get(i).getListaCompetidores().size();a++){
                info+="\t- "+escuderias.get(i).getListaCompetidores().get(a).getPiloto().getNombre() + " "+escuderias.get(i).getListaCompetidores().get(a).getPiloto().getApellidos()
                        + " puntos:"+escuderias.get(i).getListaCompetidores().get(a).getPiloto().getPuntos()+"\n";
            }
        }
        return info;
    }
     public String rankingToString(){
        String info="";
        info+="Clasificación Pilotos:\n";
        for(int i=0; i<clasificacion.size();i++){
            info+=i+1+"º "+ clasificacion.get(i).getPiloto().getNombre()+" " +clasificacion.get(i).getPiloto().getApellidos()+"\n";
        }
        return info;
    }
}

